var DebugWindow = function() {}

var Debug = Base.extend({
	win: null,
	win_id: null,
	buffer: [],
	present: true,
	constructor: null,
	last_time: null,
	start_time: 0,
	verbose: 0,

	init: function()
	{
		this.start_time = (new Date()).getTime();
	},
	start: function(win_id)
	{
		if(win_id) this.win_id = win_id;
		else if(DebugWindow) this.win = new DebugWindow(GownFullConfig.debugwin_id);
		else alert('No Debug <DIV> can be used.');
		this.flush();
	},
	clear: function()
	{
		if(this.win) this.win.clear();
		else if(this.win_id) {
			var obj = document.getElementById(this.win_id);

			obj.innerHTML = '';
		}
		this.buffer = '';
	},
	flush: function()
	{
		if((this.win || this.win_id) && this.buffer && this.buffer.length > 0) {
			for(var i=0;i<this.buffer.length;i++) this.output(this.buffer[i],true);
			this.buffer = [];
		}
	},
	output: function(str,notime)
	{
		if(!notime) {
			var ms = (new Date()).getTime() - this.start_time;
			var now = '[' + ms.toString() + ']: ';
			str = now + str;
		}

		if(this.win) { // if DebugWindow exists
			this.win.output(str);
		}
		else if(this.win_id) { // if a <DIV> is given
			var obj = document.getElementById(this.win_id);
			var msg;

			msg = document.createElement('div');
			msg.className = GownFullConfig.debugwin_msg_class_name;
			msg.innerHTML = str;
			//obj.appendChild(msg);
			obj.insertBefore(msg,obj.firstChild);
			obj.scrollTop = 0;
		}
		else { // put it in internal buffer
			this.buffer.push(str);
		}
	},
	trace: function()
	{
		if (!arguments || arguments.length < 2 || !RegExp)
		{
			return;
		}
		var vb = arguments[0];
		if(vb > this.verbose) return;

		var str = arguments[1];
		var re = /([^%]*)%('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;
		var a = b = [], numSubstitutions = 1, numMatches = 0;
		while (a = re.exec(str))
		{
			var leftpart = a[1], pPad = a[2], pJustify = a[3], pMinLength = a[4];
			var pPrecision = a[5], pType = a[6], rightPart = a[7];
			
			//alert(a + '\n' + [a[0], leftpart, pPad, pJustify, pMinLength, pPrecision);
	
			numMatches++;
			if (pType == '%')
			{
				subst = '%';
			}
			else
			{
				numSubstitutions++;
				var param = arguments[numSubstitutions];
				var pad = '';
					   if (pPad && pPad.substr(0,1) == "'") pad = leftpart.substr(1,1);
				  else if (pPad) pad = pPad;
				var justifyRight = true;
					   if (pJustify && pJustify === "-") justifyRight = false;
				var minLength = -1;
					   if (pMinLength) minLength = parseInt(pMinLength);
				var precision = -1;
					   if (pPrecision && pType == 'f') precision = parseInt(pPrecision.substring(1));
				var subst = param;
					   if (pType == 'b') subst = parseInt(param).toString(2);
				  else if (pType == 'c') subst = String.fromCharCode(parseInt(param));
				  else if (pType == 'd') subst = parseInt(param) ? parseInt(param) : 0;
				  else if (pType == 'u') subst = Math.abs(param);
				  else if (pType == 'f') subst = (precision > -1) ? Math.round(parseFloat(param) * Math.pow(10, precision)) / Math.pow(10, precision): parseFloat(param);
				  else if (pType == 'o') subst = parseInt(param).toString(8);
				  else if (pType == 's') subst = param;
				  else if (pType == 'x') subst = ('' + parseInt(param).toString(16)).toLowerCase();
				  else if (pType == 'X') subst = ('' + parseInt(param).toString(16)).toUpperCase();
			}
			str = leftpart + subst + rightPart;
		}
		this.output(str);
	},
	start_timer: function()
	{
		this.last_time = (new Date).getTime();
	},
	end_timer: function(vb,msg)
	{
		if(this.last_time == null) return;

		if(vb <= this.verbose) {
			var now = (new Date).getTime();
			this.output(msg.replace(/\$TIMER/,parseInt(now - this.last_time)) + "<br />");
		}
		this.last_time = null;
	}
});

